package net.shopxx.excel.excel;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import net.shopxx.excel.conf.ExcelFileXmlConfigure;
import net.shopxx.excel.util.ExcelFileUtil;

import org.apache.commons.lang.StringUtils;

public class ExcelFile {

	private File file;
	private InputStream input;
	private Excel excel;
	private Workbook workbook;
	private Sheet sheet;
	private List<String> fileColumnsName;
	private static boolean isMatch = true;

	private void init(String converter) {
		// ExcelFactory 为存储所有配置文件的工厂
		if (ExcelFactory.getExcels().size() == 0) {
			ExcelFactory.setExcels((new ExcelFileXmlConfigure()).configure(converter));
		}
	}

	/**
	 * Excel文件构造器 (配置文件必须同excel文件格式相同才可以解析)
	 * 
	 * @param converter
	 *            转化为DTO的映射转化器地址
	 * @param file
	 *            需要解析的excel文件
	 */
	public ExcelFile(File file, String converter) {
		init(converter);
		this.file = file;
	}

	/**
	 * Excel文件构造器 (配置文件必须同excel文件格式相同才可以解析)
	 * 
	 * @param converter
	 *            转化为DTO的映射转化器地址
	 * @param input
	 *            需要解析的excel文件流
	 */
	public ExcelFile(InputStream input, String converter) {
		init(converter);
		this.input = input;
	}

	public void createReadBook() {
		try {
			workbook = Workbook.getWorkbook(file);
			sheet = workbook.getSheet(0);
		} catch (BiffException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void createStreamReadBook() {
		try {
			workbook = Workbook.getWorkbook(input);
			sheet = workbook.getSheet(0);
		} catch (BiffException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void generateExcel(String key) {
		excel = ExcelFactory.getExcel(key);
		if (excel == null) {
			// TODO frankie log the detail
			return;
		}
	}

	public String get(int page, int row, int colum) {
		sheet = workbook.getSheet(page);
		String content = sheet.getCell(colum, row).getContents();
		return content;
	}

	public Integer getRows(Integer page) {
		Sheet sheet = workbook.getSheet(page);
		return sheet.getRows();
	}

	public Integer getColums(Integer page) {
		Sheet sheet = workbook.getSheet(page);
		return sheet.getColumns();
	}

	public boolean row2Bean(int row, Object bean) {

		if (excel == null) {
			return false;
		}

		try {
			isMatch = Class.forName(excel.getClassName()).isInstance(bean);
		} catch (Exception e) {
			// FIXME LOG THE ERROR class net.shopxx.service.impl.Student
			return false;
		}

		if (!isMatch || !validation()) {
			// FIXME LOG THE ERROR
			return false;
		}

		List<String> names = getColumnsName();
		Map<String, Column> map = excel.getColumns();
		for (int i = 0; i < names.size(); i++) {
			Column c = (Column) map.get(names.get(i));
			String content = sheet.getCell(i, row).getContents();

			if (StringUtils.isBlank(content)) {
				continue;
			}
			if ("String".equals(c.getType())) {
				ExcelFileUtil.setProperty(bean, c.getField(), content);
			} else if ("Integer".equals(c.getType())) {
				ExcelFileUtil.setProperty(bean, c.getField(), Integer.valueOf(Integer.parseInt(content)));
			} else if ("Float".equals(c.getType())) {
				ExcelFileUtil.setProperty(bean, c.getField(), Float.valueOf(Float.parseFloat(content)));
			} else if ("Long".equals(c.getType())) {
				ExcelFileUtil.setProperty(bean, c.getField(), Long.valueOf(Long.parseLong(content)));
			} else {
				// FIXME LOG THE ERROR
			}
		}
		return true;
	}

	public List<String> getColumnsName() {
		return excel.getColumnsName();
	}

	/**
	 * 验证Excel文件头部字段和配置字段是否一致
	 * 
	 * @return
	 */
	public boolean validation() {
		if (getFileColumnsName().size() == 0)
			getFileColumnsName();
		for (int i = 0; i < excel.getColumnsName().size(); i++)
			if (!fileColumnsName.contains(excel.getColumnsName().get(i))) {
				// FIXME LOG THE ERROR
				return false;
			}
		isMatch = true;
		return true;
	}

	/**
	 * 获取Excel文件头部字段数据
	 * 
	 * @return
	 */
	public List<String> getFileColumnsName() {
		int columns = sheet.getColumns();
		if (columns == 0) {
			// FIXME LOG THE ERROR
			return null;
		}
		fileColumnsName = new ArrayList<String>();
		for (int i = 0; i < columns; i++) {
			fileColumnsName.add(sheet.getCell(i, 0).getContents().trim());
		}

		return fileColumnsName;
	}

	public void closeReadBook() {
		workbook.close();
	}

}
